package com.syscom.server.qc.cacheManager;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import com.syscom.frmcommon.util.ArithUtil;
import com.syscom.safe.cache.SafeCacheException;
import com.syscom.safe.cache.SafeCacheManager;
import com.syscom.server.cache.safeCache.AccuRuleBrokerCache;
import com.syscom.server.cache.safeCache.vo.AccuRuleBrokerCacheVo;
import com.syscom.server.constant.CacheConstant;

/**
 * @author Jean
 */
public class AccuRule4CacheManager {
	@SuppressWarnings("unused")
	private transient static final String mark = "10BCC85DDC54DDF27A18E78A2AA7EB50A27C9789E7CDBE9FD4DD9C9DC56D7247A585625B8AE77885";
	private static Logger mLogger = Logger.getLogger(AccuRule4CacheManager.class.getName());
	private static AccuRule4CacheManager instance = new AccuRule4CacheManager();
	
	private AccuRuleBrokerCache mAccuRuleBrokerCache = null;
	
	public static AccuRule4CacheManager getInstance() { return instance; }
	
	private AccuRule4CacheManager() {
		mAccuRuleBrokerCache = (AccuRuleBrokerCache) SafeCacheManager.getInstance().getCache(CacheConstant.ACCU_RULET_4);
	}
	
	public AccuRuleBrokerCacheVo getRuleValue(String sKey) {
		AccuRuleBrokerCacheVo ruleVo = null;
		try {
			ruleVo = (AccuRuleBrokerCacheVo) mAccuRuleBrokerCache.getVoForReading(sKey);
		}
		catch (SafeCacheException e) {
			if (mLogger.isEnabledFor(Level.ERROR)) {
				mLogger.log(Level.ERROR, e.getMessage(), e);
        	}
		}
		
		return ruleVo;
	}

	public void releaseAccuRuleVoFromReading(AccuRuleBrokerCacheVo accuRuleVo) {
		if (accuRuleVo == null) return;

		try {
			mAccuRuleBrokerCache.releaseVoFromReading(accuRuleVo);		
		}
		catch (SafeCacheException e) {
			if (mLogger.isEnabledFor(Level.ERROR)) {
				mLogger.log(Level.ERROR, e.getMessage(), e);
        	}
		}
	}
	
	public AccuRuleBrokerCacheVo updAccuRuleByLevel(String sKey) {
		try {
			AccuRuleBrokerCacheVo ruleVo = (AccuRuleBrokerCacheVo) mAccuRuleBrokerCache.getVoForUpdating(sKey);
			return ruleVo;
		}
		catch (SafeCacheException e) {
			if (mLogger.isEnabledFor(Level.ERROR)) {
				mLogger.log(Level.ERROR, e.getMessage(), e);
        	}
		}
		
		return null;
	}

	public void releaseAccuRuleVoFromUpdating(AccuRuleBrokerCacheVo ruleVo) {
		if (ruleVo == null) return;
		
		try {
			mAccuRuleBrokerCache.releaseVoFromUpdating(ruleVo);
		}
		catch (SafeCacheException e) {
			if (mLogger.isEnabledFor(Level.ERROR)) {
				mLogger.log(Level.ERROR, e.getMessage(), e);
        	}
		}
	}

	public boolean insAccuRuleByLevel(AccuRuleBrokerCacheVo accuRuleVo) {
		if (accuRuleVo == null) return false;
		
		try {
			return mAccuRuleBrokerCache.insertVoIfNotExist((AccuRuleBrokerCacheVo) accuRuleVo);
		}
		catch (SafeCacheException e) {
			if (mLogger.isEnabledFor(Level.ERROR)) {
				mLogger.log(Level.ERROR, e.getMessage(), e);
        	}
		}
		
		return false;
	}
	
	public double updateRuleValue(int iRuleId, String sProdId, AccuRuleBrokerCacheVo newBrokerVo, double dValue) {
		AccuRuleBrokerCacheVo updAccuRuleVo  = null;
		double dRuleValue = 0;
		
		try {
			newBrokerVo.setAccuValue(dValue);
			
			if (!insAccuRuleByLevel(newBrokerVo)) {
				String sAccuKey = AccuRuleBrokerCacheVo.getKeyString(sProdId, iRuleId);
				updAccuRuleVo = (AccuRuleBrokerCacheVo) updAccuRuleByLevel(sAccuKey);
				
				if (updAccuRuleVo != null) {
					dRuleValue = ArithUtil.add(updAccuRuleVo.getAccuValue(), dValue);
					updAccuRuleVo.setAccuValue(dRuleValue);
				}
			}
			else {
				dRuleValue = dValue;
			}
		}
		finally {
			releaseAccuRuleVoFromUpdating(updAccuRuleVo);
		}
		
		return dRuleValue; 
	}

	public void updateAndCoverRuleValue(int iRuleId, String sProdId, AccuRuleBrokerCacheVo newBrokerVo, double dRuleValue) {
		AccuRuleBrokerCacheVo updAccuRuleVo  = null;
		
		try {
			newBrokerVo.setAccuValue(dRuleValue);
			
			if (!insAccuRuleByLevel(newBrokerVo)) {
				String sAccuKey = AccuRuleBrokerCacheVo.getKeyString(sProdId, iRuleId);
				updAccuRuleVo = (AccuRuleBrokerCacheVo) updAccuRuleByLevel(sAccuKey);
				
				if (updAccuRuleVo != null) {
					updAccuRuleVo.setAccuValue(dRuleValue);
				}
			}
		}
		finally {
			releaseAccuRuleVoFromUpdating(updAccuRuleVo);
		}
	}

	public void rollbackRuleValue(int iRuleId, String sProdId, double dValue) {
		AccuRuleBrokerCacheVo updAccuRuleVo  = null;
		double dRuleValue = 0;
		
		try {
			String sAccuKey = AccuRuleBrokerCacheVo.getKeyString(sProdId, iRuleId);
			updAccuRuleVo = (AccuRuleBrokerCacheVo) updAccuRuleByLevel(sAccuKey);
			
			if (updAccuRuleVo != null) {
				dRuleValue = ArithUtil.sub(updAccuRuleVo.getAccuValue(), dValue);
				updAccuRuleVo.setAccuValue(dRuleValue);
			}
		}
		finally {
			releaseAccuRuleVoFromUpdating(updAccuRuleVo);
		}
	}

}
